package com.xxx.util.jwt;

import com.xxx.config.exception.GenExceptCode;
import com.xxx.config.exception.ServiceException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.core.UriInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 令牌工具类
 *
 * @version 1.0
 * @since 1.0
 */
@Slf4j
public class JwtUtil {
    private static final String secret = "AX0XHH121wqXZM1xie2dian3shen4me5hao6le7890bu0zhi0dao";

    public static Integer getUserIdFromToken(String token) {
        Integer userId;
        try {
            Claims claims = getClaimsFromToken(token);
            userId = (Integer) claims.get("userId");
        } catch (Exception e) {
            throw new ServiceException(GenExceptCode.Token_Invalid.name(), "token解析失败,token异常或已经过期！");
        }
        return userId;
    }

    /**
     * 生成令牌
     *
     * @param userId  用户id
     * @param expires 毫秒
     * @return token
     */
    public static String generateToken(Integer userId, long expires) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userId);

        byte[] keyBytes = Decoders.BASE64.decode(secret);
        Key key = Keys.hmacShaKeyFor(keyBytes);

        JwtBuilder builder = Jwts.builder()
                .issuedAt(generateCurrentDate())
                .claims(claims)
                .signWith(key);
        // 设置过期时间
        if (expires >= 0) {
            long expMillis = getCurrentTimeMillis() + expires;
            Date exp = new Date(expMillis);
            builder.expiration(exp);
        }
        return builder.compact();
    }

    /**
     * 从请求头中获取令牌
     */
    public static String getJwtFromHeader(ContainerRequestContext requestContext) {
        String auth = requestContext.getHeaderString("Authorization");
        if (StringUtils.isEmpty(auth)) {
            return null;
        }
        return auth.replaceFirst("[B|b][E|e][A|a][R|r][E|e][R|r] ", "").replace(" ", "");
    }

    /**
     * 从请求URL中获取令牌
     */
    public static String getJwtFromUrl(ContainerRequestContext requestContext) {
        UriInfo uriInfo = requestContext.getUriInfo();
        // 从UriInfo对象中获取查询参数
        MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
        // 获取特定的查询参数值
        String auth = queryParams.getFirst("_t");
        if (StringUtils.isEmpty(auth)) {
            return null;
        }
        return auth.replaceFirst("[B|b][E|e][A|a][R|r][E|e][R|r] ", "").replace(" ", "");
    }


    private static Claims getClaimsFromToken(String token) {
        Claims claims;
        try {

            byte[] keyBytes = Decoders.BASE64.decode(secret);
            Key key = Keys.hmacShaKeyFor(keyBytes);

            claims = Jwts.parser()
                    .setSigningKey(key)
                    .build()
                    .parseSignedClaims(token)
                    .getPayload();
        } catch (Exception e) {
            throw new ServiceException(GenExceptCode.Token_Invalid.name(), "token解析失败,token异常或已经过期！");
        }
        return claims;
    }

    private static long getCurrentTimeMillis() {
        return new Date().getTime();
    }

    private static Date generateCurrentDate() {
        return new Date(getCurrentTimeMillis());
    }


}
